package com.devops

import groovy.json.JsonOutput
import hudson.model.Run
import hudson.model.Result
import hudson.model.Cause.UserIdCause
import org.jenkinsci.plugins.workflow.job.WorkflowRun
import org.jenkinsci.plugins.workflow.graph.FlowNode
import org.jenkinsci.plugins.workflow.graph.StepNode
import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException

class PipelineReporter {
    def steps
    def stageName
    def errorMessage
    
    PipelineReporter(steps) {
        this.steps = steps
    }

    def updateFailureInfo(String name, String message) {
        this.stageName = name
        this.errorMessage = message
    }

    def reportPipelineStatus() {
        def build = steps.currentBuild
        def status = build.result.toString()
  
        switch(status) {
            case "SUCCESS":
                reportSuccess()
                break
            case "FAILURE":
                reportFailure()
                break
            case "ABORTED":
                reportAborted()
                break
            default:
                steps.echo "Unknown build status: ${status}"
                break
        }
    }
    
    def reportSuccess(Map config = [:]) {
        def pipelineData = collectPipelineData(config)
        pipelineData.buildStatus = "成功"
        sendPipelineData(pipelineData)
    }
    
    def reportFailure(Map config = [:]) {
        def pipelineData = collectPipelineData(config)
        pipelineData.buildStatus = "失败"
        sendPipelineData(pipelineData)
    }
    
    def reportAborted(Map config = [:]) {
        def pipelineData = collectPipelineData(config)
        pipelineData.buildStatus = "取消"
        def abortReason = config.abortReason ?: "流水线被手动终止!"
        def abortUser = getAbortUser()
        if (abortUser) {
            abortReason = "${abortReason} 取消用户：${abortUser}"
        }
        pipelineData.failureReason = abortReason
        
        sendPipelineData(pipelineData)
    }
    
     private def collectPipelineData(Map config) {
        def env = steps.env
        def build = steps.currentBuild
        
        def repoName = config.repoName ?: env.REPO_NAME ?: ""
        def prId = config.prId ?: env.PR_ID ?: 0
        def nodeIp = config.nodeIp ?: env.NODE_IP ?: ""
        if (prId instanceof String && prId.isNumber()) {
            prId = prId as Integer
        } else if (!(prId instanceof Integer)) {
            prId = 0
        }
        def executor = getExecutorInfo()?.executorName
        def executeType = (prId != null && prId != 0) ? "合并PR" : "开发测试"
        
        def pipelineData = [
            jobName: env.JOB_NAME,
            buildId: env.BUILD_ID as Integer,
            executor: executor,
            executeType: executeType,
            repoName: repoName,
            prId: prId,
            nodeIp: nodeIp,
            startTime: formatTimestamp(build.startTimeInMillis),
            endTime: formatTimestamp(System.currentTimeMillis()),
            duration: calculateDuration(build.startTimeInMillis, System.currentTimeMillis()),
            buildStatus: "",
            failedNode: stageName ?: "",
            failureReason: errorMessage ?: ""
        ]

        return pipelineData
    }
    
    private def sendPipelineData(data) {
        try {
            def json = JsonOutput.toJson(data)
            steps.echo "Sending pipeline data: ${JsonOutput.prettyPrint(json)}"

            // 确保JENKINS_URL存在并以/结尾
            def jenkinsUrl = steps.env.JENKINS_URL
            if (!jenkinsUrl.endsWith('/')) {
                jenkinsUrl += '/'
            }
            def apiUrl = "${jenkinsUrl}data-api/pipeline"
            
            def response = steps.httpRequest(
                url: apiUrl,
                httpMode: 'POST',
                requestBody: json,
                contentType: 'APPLICATION_JSON_UTF8',
                timeout: 30
            )
            
            if (response.status == 200) {
                steps.echo "Pipeline data reported successfully"
            } else {
                steps.echo "Failed to report pipeline data. Status: ${response.status}"
            }
        } catch (Exception e) {
            steps.echo "Error reporting pipeline data: ${e.getMessage()}"
        }
    }
    
    private def formatTimestamp(long timestamp) {
        def date = new Date(timestamp)
        return date.format("yyyy-MM-dd HH:mm:ss")
    }
    
    private def calculateDuration(long start, long end) {
        def durationSecs = (end - start) / 1000
        // Convert to double to avoid BigDecimal modulo issues
        def durationDouble = durationSecs.toDouble()
        def hours = Math.floor(durationDouble / 3600) as Integer
        def minutes = Math.floor((durationDouble % 3600) / 60) as Integer
        def seconds = Math.floor(durationDouble % 60) as Integer
        return "${hours}小时${minutes}分钟${seconds}秒"
    }
    
    private def getAbortedStage() {
        return steps.env.STAGE_NAME ?: "Unknown Stage"
    }
    
    private def getAbortUser() {
        try {
            // 尝试从当前构建获取用户信息
            def build = steps.currentBuild.rawBuild
            def causes = build.getCauses()
            if (causes) {
                for (def cause : causes) {
                    if (cause.getClass().simpleName.contains('UserIdCause')) {
                        return cause.getUserId() ?: cause.getUserName()
                    }
                }
            }
            
            // 尝试从环境变量获取
            def user = steps.env.BUILD_USER ?: steps.env.USER_NAME ?: steps.env.CAUSE_USER ?: ""
            if (user) {
                return user
            }
        } catch (Exception e) {
            steps.echo "无法获取取消用户: ${e.getMessage()}"
        }
        return null
    }
    
    private Map getExecutorInfo() {
        // 初始化默认值
        def executorInfo = [
            executorId: "unknown",
            executorName: "未知用户",
            isManualTrigger: false
        ]

        // 查找UserIdCause（手动触发的标识）
        WorkflowRun workflowRun = steps.currentBuild.rawBuild
        UserIdCause userCause = workflowRun.getCause(UserIdCause)
        if (userCause) {
            executorInfo.isManualTrigger = true
            executorInfo.executorId = userCause.getUserId() ?: "anonymous"
            
            // 尝试获取用户全名
            try {
                def user = hudson.model.User.get(userCause.getUserId())
                executorInfo.executorName = user.getFullName() ?: user.getId()
            } catch (Exception e) {
                // 如果用户不存在或获取失败，使用ID作为名称
                executorInfo.executorName = userCause.getUserId() ?: "anonymous"
            }
        } else {
            echo "[WARN] 此构建不是手动触发，无法获取执行人信息"
        }

        return executorInfo
    }
}